<template>
  <div class="containers" ref="content">
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
    <ul class="buttons">
      <li>下载</li>
      <li>
        <a ref="saveDiagram" href="javascript:;" title="download BPMN diagram">BPMN diagram</a>
      </li>
      <li>
        <a ref="saveSvg" href="javascript:;" title="download as SVG image">SVG image</a>
      </li>
      <li>
        <Button type="primary" @click="save" :disabled="!xmlStr">保存</Button>
      </li>
      <li>
        <Button type="primary" @click="modal=true">新建项目</Button>
      </li>
      <li>
        <Button type="primary" @click="editModel">编辑模型</Button>
      </li>
    </ul>
    <Modal
      v-model="modal"
      title="Common Modal dialog box title"
      @on-ok="handleOk('modelForm')"
      @on-cancel="handleCancel('modelForm')"
    >
      <Form ref="modelForm" :model="formInline" :rules="ruleInline"  :label-width="80">
        <FormItem label="项目名称" prop="modelName">
          <Input type="text" v-model="formInline.modelName" placeholder="请输入项目名称" />
        </FormItem>
      </Form>
    </Modal>
  </div>
</template>

<script>
// 引入相关的依赖
  import objtree from 'objtree'
  import BpmnModeler from 'bpmn-js/lib/Modeler'
  import propertiesPanelModule from 'bpmn-js-properties-panel'
  import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
  import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
// 引入保存要用的API接口
// import {saveBpmnData} from '../../api/modeler'
import customTranslate from '../assets/customTranslate/customTranslate';

// 引入tab的配置文件
import magicPropertiesProviderModule from '../assets/provider/magic';
import magicModdleDescriptor from '../assets/descriptors/magic';

export default {
  data() {
    return {
      id: null,
      bpmnModeler: null,
      container: null,
      canvas: null,
      xmlStr: null,
      processName: "",
      modal: false,
      formInline: {
        modelName: ''
      },
      ruleInline: {
        modelName: [{
          required: true,
          message: '请填写项目名称',
          trigger: 'blur'
        }]
      }
    };
  },
  methods: {
    createNewDiagram() {
      // 定义空的图的模型，这里我们根据用户输入，利用字符串的拼接，定义了这个流程图的名字，不需要的就把字符串的拼接去掉。
      // 把 <bpmn2:process id=\"Process_1\" name=\"" + this.processName + "\" isExecutable=\"false\"> 改成 <bpmn2:process id=\"Process_1\" isExecutable=\"false\"> 就好
      const newDiagramXML =
        '<?xml version="1.0" encoding="UTF-8"?>\r\n<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn">\r\n  <bpmn2:process id="Process_1" name="' +
        this.processName +
        '" isExecutable="false">\r\n    <bpmn2:startEvent id="StartEvent_1"/>\r\n  </bpmn2:process>\r\n  <bpmndi:BPMNDiagram id="BPMNDiagram_1">\r\n    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">\r\n      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\r\n        <dc:Bounds height="36.0" width="36.0" x="412.0" y="240.0"/>\r\n      </bpmndi:BPMNShape>\r\n    </bpmndi:BPMNPlane>\r\n  </bpmndi:BPMNDiagram>\r\n</bpmn2:definitions>';
      this.bpmnModeler.importXML(newDiagramXML, (err) => {
        if (err) {
          console.error(err);
        }
        this.bpmnModeler.get('canvas').zoom('fit-viewport');
      });
    },

    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveSVG(done) {
      // 把传入的done再传给bpmn原型的saveSVG函数调用
      this.bpmnModeler.saveSVG(done);
    },
    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveDiagram(done) {
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml);
      });
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data);
      
      // 获取到图的xml，保存就是把这个xml提交给后台
      this.xmlStr = data;
      
      // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
      if (data) {
        link.className = "active";
        link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
        link.download = name;
      } else {
        // xml不存在时
      }
    },

    // 保存修改操作
    save() {
      // 传给后台的参数
      let params = {
        id: this.id,
        bpmnXml: this.xmlStr
      };
      // 调用API接口
      // saveBpmnData(params).then(res => {
      //          console.log(res)
      //          console.log(this.xmlStr)
      //  })
      localStorage.setItem('bpmnModel', JSON.stringify(params));
    },
    handleOk(refsName) {
      this.$refs[refsName].validate((validate) => {
        if (validate) {
          this.processName = this.formInline.modelName;
          this.createNewDiagram();
          this.$refs[refsName].resetFields();
        } else {
          this.$Message.error('Fail!');
        }
      })
    },
    handleCancel(refsName) {
      this.$refs[refsName].resetFields();
    },
    // 编辑模型操作
    editModel() {
      this.$router.push({name: 'GetHelloWorld'})
    }
  },
  mounted() {
    this.container = this.$refs.content;
    const canvas = this.$refs.canvas;
    const customTranslateModule = {
      translate: [ 'value', customTranslate ]
    };

    this.bpmnModeler = new BpmnModeler({
      container: canvas,
      // 快捷键
      keyboard: {
        bindTo: window
      },
      //添加控制板
      propertiesPanel: {
        parent: "#js-properties-panel"
      },
      additionalModules: [
        // 左侧的工具栏及节点
        propertiesPanelModule,
        // 右侧的工具栏
        propertiesProviderModule,
        magicPropertiesProviderModule,
        customTranslateModule
      ],
      moddleExtensions: {
        camunda: camundaModdleDescriptor,
        magic: magicModdleDescriptor,
      }
    });

    // 下载画图
    let _this = this;
    // 获取a标签dom节点
    const downloadLink = this.$refs.saveDiagram;
    const downloadSvgLink = this.$refs.saveSvg;
    // 给图绑定事件，当图有发生改变就会触发这个事件* **（绑定事件操作）
    this.bpmnModeler.on("commandStack.changed", function() {
      // 保存svg格式的图片供后面下载
      _this.saveSVG(function(err, svg) {
        _this.setEncoded(downloadSvgLink, "diagram.svg", err ? null : svg);
      });
      // 保存BPMN diagram格式的文件供后面下载
      _this.saveDiagram(function(err, xml) {
        // if (!err) {
        //   // 转换为json解构
        //   const xotree = new objtree();
        //   const xml_json = xotree.parseXML(xml);
        //   console.log(111, xml_json);
        //   // 转换为xmlStr解构
        //   const xml_str = xotree.writeXML(xml_json);
        //   console.log(222,xml_str);
        // }
        _this.setEncoded(downloadLink, "diagram.bpmn", err ? null : xml);
      });
    });
  }
};
</script>

<style lang="scss">
/*左边工具栏以及编辑节点的样式*/
@import "bpmn-js/dist/assets/diagram-js.css";
@import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
@import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
@import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
/*右边工具栏样式*/
@import "bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css";
.containers {
  position: absolute;
  background-color: #ffffff;
  width: 100%;
  height: 90%;
}
.canvas {
  width: 100%;
  height: 100%;
}
.panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
}
.buttons {
  position: absolute;
  left: 30px;
  bottom: 20px;
  & > li {
    display: inline-block;
    margin: 5px;
    & > a {
      color: #999;
      background: #eee;
      cursor: not-allowed;
      padding: 8px;
      border: 1px solid #ccc;
      &.active {
        color: #333;
        background: #fff;
        cursor: pointer;
      }
    }
  }
  
}
</style>
